package com.codingxyz.simple.nio;

import org.junit.jupiter.api.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class TestChannel {


    /**
     * 分散和聚集
     */
    @Test
    public void test4() throws IOException {

        RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw");

        /**
         * 获取通道
         */
        FileChannel channel = raf1.getChannel();

        ByteBuffer buf1 = ByteBuffer.allocate(100);
        ByteBuffer buf2 = ByteBuffer.allocate(1024);

        /**
         * 分散读取
         */
        ByteBuffer[] bufs = {buf1,buf2};

        channel.read(bufs);

        for(ByteBuffer buffer:bufs){
            buffer.flip();
        }

        System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
        System.out.println("++++++++++++++++++++++++++++++++++++++++++");
        System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));


        /**
         * 聚集写入
         */
        RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw");
        FileChannel fileChannel = raf2.getChannel();
        fileChannel.write(bufs);

        fileChannel.close();
        channel.close();


    }

    public void test3(){

        FileChannel inputFileChannel = null;
        FileChannel ouputFinleChannel = null;


        try {
            inputFileChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
            ouputFinleChannel = FileChannel.open(Paths.get("3.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

            inputFileChannel.transferTo(0,inputFileChannel.size(),ouputFinleChannel);

            //内存映射文件
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ouputFinleChannel!=null){
                try {
                    ouputFinleChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(inputFileChannel!=null){
                try {
                    inputFileChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Test
    public void test2(){

        FileChannel inputFileChannel = null;
        FileChannel ouputFinleChannel = null;
        MappedByteBuffer inMapperBuff = null;
        MappedByteBuffer outMapperBuff = null;


        try {
            inputFileChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);

            ouputFinleChannel = FileChannel.open(Paths.get("3.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

        //内存映射文件
         inMapperBuff = inputFileChannel.map(FileChannel.MapMode.READ_ONLY,0,inputFileChannel.size());
         outMapperBuff = ouputFinleChannel.map(FileChannel.MapMode.READ_WRITE,0,inputFileChannel.size());

        //直接对缓存区数据进行读写操作
        byte[] dst = new byte[inMapperBuff.limit()];
        inMapperBuff.get(dst);
        outMapperBuff.put(dst);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ouputFinleChannel!=null){
                try {
                    ouputFinleChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(inputFileChannel!=null){
                try {
                    inputFileChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Test
    public void test1(){

        FileInputStream input = null;
        FileOutputStream out = null;
        FileChannel readChannel = null;
        FileChannel writeChannel = null;

        try {

            input = new FileInputStream("1.jpg");
            out = new FileOutputStream("2.jpg");

             readChannel = input.getChannel();
             writeChannel = out.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (readChannel.read(buffer)!=-1){
                buffer.flip();
                writeChannel.write(buffer);
                buffer.clear();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(writeChannel!=null){
                try {
                    writeChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(readChannel!=null){
                try {
                    readChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(input!=null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
